package com.yql.framework.shiro.service;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.yql.commonextend.config.OssConfig;
import com.yql.commonextend.config.UassConfig;
import com.yql.commonextend.utils.BusinessMsg;
import com.yql.commonextend.utils.ToolDES;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import com.yql.common.constant.Constants;
import com.yql.common.constant.ShiroConstants;
import com.yql.common.constant.UserConstants;
import com.yql.common.core.domain.entity.SysUser;
import com.yql.common.enums.UserStatus;
import com.yql.common.exception.user.CaptchaException;
import com.yql.common.exception.user.UserBlockedException;
import com.yql.common.exception.user.UserDeleteException;
import com.yql.common.exception.user.UserNotExistsException;
import com.yql.common.exception.user.UserPasswordNotMatchException;
import com.yql.common.utils.DateUtils;
import com.yql.common.utils.MessageUtils;
import com.yql.common.utils.ServletUtils;
import com.yql.common.utils.ShiroUtils;
import com.yql.framework.manager.AsyncManager;
import com.yql.framework.manager.factory.AsyncFactory;
import com.yql.system.service.ISysUserService;
import org.springframework.web.client.RestTemplate;

/**
 * 登录校验方法
 * 
 * @author ruoyi
 */
@Component
@Slf4j
public class SysLoginService
{
    @Autowired
    private SysPasswordService passwordService;

    @Autowired
    private ISysUserService userService;


    /**
     * 登录
     */
    public SysUser login(String username, String password)
    {
        // 验证码校验
        if (ShiroConstants.CAPTCHA_ERROR.equals(ServletUtils.getRequest().getAttribute(ShiroConstants.CURRENT_CAPTCHA)))
        {
            AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error")));
            throw new CaptchaException();
        }
        // 用户名或密码为空 错误
        if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password))
        {
            AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("not.null")));
            throw new UserNotExistsException();
        }

        //非行内登录
        if(!UassConfig.getIsUass()){
            // 密码如果不在指定范围内 错误
            if (password.length() < UserConstants.PASSWORD_MIN_LENGTH
                    || password.length() > UserConstants.PASSWORD_MAX_LENGTH)
            {
                AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
                throw new UserPasswordNotMatchException();
            }

            // 用户名不在指定范围内 错误
            if (username.length() < UserConstants.USERNAME_MIN_LENGTH
                    || username.length() > UserConstants.USERNAME_MAX_LENGTH)
            {
                AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
                throw new UserPasswordNotMatchException();
            }
        }


        // 查询用户信息
        SysUser user = userService.selectUserByLoginName(username);

        /**
        if (user == null && maybeMobilePhoneNumber(username))
        {
            user = userService.selectUserByPhoneNumber(username);
        }

        if (user == null && maybeEmail(username))
        {
            user = userService.selectUserByEmail(username);
        }
        */

        if (user == null)
        {
            AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.not.exists")));
            throw new UserNotExistsException();
        }
        if (UserStatus.DELETED.getCode().equals(user.getDelFlag()))
        {
            AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.delete")));
            throw new UserDeleteException();
        }
        
        if (UserStatus.DISABLE.getCode().equals(user.getStatus()))
        {
            AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.blocked", user.getRemark())));
            throw new UserBlockedException();
        }

        //行内
        if(UassConfig.getIsUass()){
            BusinessMsg msg = checkUassAccount(username, password,UassConfig.getUassPRIVACY_KEY());
            if (!msg.getCode().equals("200")) {
                AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
                throw new UserBlockedException();
            }
        }else{
            passwordService.validate(user, password);
        }

        AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
        recordLoginInfo(user);
        return user;
    }

    /**
     * 校验UASS账号
     *
     * @param account
     * @param password uass密码
     * @return
     */
    public BusinessMsg checkUassAccount(String account, String password, String privatekey) {
        BusinessMsg msg = new BusinessMsg();
//        String privatekey = null;
        try {
            log.info("开始调用uass账号服务}");
            RestTemplate restTemplate = new RestTemplate();
            password = ToolDES.encrypt(password, privatekey);
            String url = UassConfig.getUassurl() + "?loginname=" + account + "&password="
                    + password + "&srcsys="+UassConfig.getSrcsys() ;
            log.info("url" + url);
            ResponseEntity<String> responseEntity = restTemplate.exchange(url,
                    HttpMethod.GET, null, String.class);
            log.info("uass账号服务返回结果：" + responseEntity.getBody());
            if (responseEntity != null
                    && responseEntity.getStatusCode() == HttpStatus.OK) {
                String sessionData = responseEntity.getBody();
                log.info("ST令牌返回：" + sessionData);
                JSONObject jsonObject = JSONUtil.parseObj(sessionData);
                String err = jsonObject.getStr("err");
                String errinfo = jsonObject.getStr("errinfo");
                if (err.equals("0")) {
                    String tourl = jsonObject.getStr("tourl");
                    //tourl = "&srcsys=ccbgoGold";
                    // uass登录
                    ResponseEntity<String> tourlEntity = restTemplate.exchange(
                            tourl, HttpMethod.GET, null, String.class);
                    if (tourlEntity != null
                            && tourlEntity.getStatusCode() == HttpStatus.OK) {
                        String tosessionData = tourlEntity.getBody();
                        log.info("uass登录返回：" + tosessionData);
                        JSONObject jsonObject2 = JSONUtil.parseObj(tosessionData);
                        String errinfo2 = jsonObject2.getStr("errinfo");
                        String err2 = jsonObject2.getStr("err");
                        if ("0".equals(err2)) {
                            msg.setCode("200");
                            msg.setMessage("认证成功");
                            String empid = jsonObject2.getJSONObject(
                                    "principal").getStr("empeId");
                            msg.setData(empid);
                            return msg;
                        } else {
                            msg.setCode("500");
                            msg.setMessage(errinfo2);
                            return msg;
                        }
                    } else {
                        msg.setCode("500");
                        msg.setMessage("认证失败，请检查用户名和密码");
                        return msg;
                    }
                } else {
                    log.info("======ST令牌生成失败," + errinfo);
                    msg.setCode("500");
                    msg.setMessage(errinfo);
                    return msg;
                }
            } else {
                msg.setCode("500");
                msg.setMessage("认证失败，请检查用户名和密码");
                return msg;
            }
        } catch (Exception e) {
            log.info("调用uass账号服务异常：{}", e);
            msg.setCode("500");
            msg.setMessage("调用UASS认证服务失败");
            return msg;
        }
    }


    /**
    private boolean maybeEmail(String username)
    {
        if (!username.matches(UserConstants.EMAIL_PATTERN))
        {
            return false;
        }
        return true;
    }

    private boolean maybeMobilePhoneNumber(String username)
    {
        if (!username.matches(UserConstants.MOBILE_PHONE_NUMBER_PATTERN))
        {
            return false;
        }
        return true;
    }
    */

    /**
     * 记录登录信息
     */
    public void recordLoginInfo(SysUser user)
    {
        user.setLoginIp(ShiroUtils.getIp());
        user.setLoginDate(DateUtils.getNowDate());
        userService.updateUserInfo(user);
    }
}
